home *** CD-ROM | disk | FTP | other *** search
- TITLE SWPKEYAT -- Swap IBM-PC/AT Keys
- SUBTTL History
-
- ; This program intercepts the IBM-PC/AT's keyboard hardware interrupt
- ; and messes around with the keyboard scan codes, specifically to swap the
- ; "Esc" and "~" keys. It then returns to the ROM BIOS for the remainder
- ; of the keyboard interrupt processing.
-
- ; Note that the only way that I can return to the ROM BIOS for the
- ; remainder of the keyboard processing is to jump to a nonstandard known
- ; location in ROM. This is an unfortunate practice. The only other
- ; option I can see is for SWPKEYAT to contain it's own copy of the entire
- ; keyboard interrupt code. However, I don't have time to do this yet.
-
- ; Because of the way that SWPKEYAT interacts with the keyboard
- ; hardware interrupt vector and the BIOS ROM, you must load this program
- ; BEFORE you load other keyboard processing programs, such as ScrollMate
- ; and BUF160. Perhaps with more effort I could devise a cleaner interface.
-
- ; Another problem is that some programs, such as Lugaru Epsilon,
- ; substitute their own keyboard scan interrupt routines while they are
- ; active. In order to easily patch such programs I have defined a special
- ; interrupt number, INT 3FH, which acts like an IN from the keyboard data
- ; port with the appropriate scan codes swapped. (INT 3FH is the last
- ; "Reserved for DOS" interrupt. DOS 3.10 doesn't use it, but that's no
- ; guarantee about future availability.)
-
- ; This version is set up for the IBM-PC/AT ROM BIOS as documented in the
- ; March 1984 edition of the Technical Reference for the IBM Personal Computer
- ; AT, keyboard BIOS module dated 01/04/84. Warning! Ignore the IBM PC/AT
- ; Technical Reference section "Key Scan Codes", starting on p. 4-10. It's
- ; completely bogus. Also, ignore the "break code prefix". Instead, relay on
- ; the BIOS ROM listing (p. 5-28, p. 5-115 and on) in earlier editions of
- ; the Technical Reference (like the Aug 1981 edition). The only new key on
- ; the AT, Sys Req, has scan code 84 (dec).
-
-
- ; swpkeyat.asm 10 Jul 85 Craig Milo Rogers at USC/ISI
- ; Improved some of the comments.
- ; swpkeyat.asm 27 Jun 85 Craig Milo Rogers at USC/ISI
- ; Created this program to swap the ESC key on the IBM-PC/AT with the
- ; tilde/grave key.
-
- PAGE
- SUBTTL Declarations
-
- KB_DATA EQU 060H ; Keyboard data port.
- BREAK_BIT EQU 080H ; Break-contact scan modifier.
- ESC_SCAN EQU 001H ; Scan code for the ESC key.
- TILDE_SCAN EQU 029H ; Scan code for tilde/grave key.
-
- STATUS_PORT EQU 064H ; Keyboard status port.
- INPT_BUF_FULL EQU 002H ; Input-buffer-full bit.
- DIS_KBD EQU 0ADH ; Disable-keyboard command.
-
- KB_INUM EQU 009H ; Keyboard hardware interrupt number.
-
- SCAN_INUM EQU 03FH ; Keyboard scan request interrupt
- ; number.
-
-
- ; The following two segments are used to interface this code to the
- ; ROM BIOS.
-
- BIOSDATA SEGMENT AT 40H ; BIOS data area in RAM.
-
- BIOSDATA ENDS
-
-
- BIOSROM SEGMENT AT 0F000H ; Known BIOS locations in ROM.
-
- ORG 03054H+0ABH-08CH ; Place to reenter the keyboard
- KB_INT_1A LABEL FAR ; hardware interrupt.
-
- BIOSROM ENDS ; End of BIOS ROM segment.
-
-
-
- CODESEG SEGMENT ; The code segment for this module.
- ASSUME CS:CODESEG ; Always in CS.
- ; Configure for a .COM file: start
- ; with the Program Segment Prefix.
-
- ORG 02CH ; The PSP environment pointer.
- ENV_SEG LABEL WORD
-
- ORG 100H ; Start of .COM execution.
- BEGIN: JMP INIT ; Goto to code which initializes
- ; everything.
-
- PAGE
- SUBTTL KB_INT -- Keyboard Interrupt
-
- ; Control passes here when a message is ready from the keyboard.
-
- KB_INT PROC FAR
- STI ; Enable interrupts.
- PUSH BP ; Save the registers just like
- PUSH AX ; the ROM.
- PUSH BX
- PUSH CX
- PUSH DX
- PUSH SI
- PUSH DI
- PUSH DS
- PUSH ES
- CLD ; Forward direction.
-
- MOV AX,BIOSDATA ; Establish pointer to BIOS data.
- MOV DS,AX
-
- ; Disable the keyboard:
- SUB CX,CX ; Clear counter for max cycles.
- CLI ;;; Disable interrupts.
- LOOP1: IN AL,STATUS_PORT ;;; Read the keyboard status port.
- TEST AL,INPT_BUF_FULL ;;; Is the command buffer still full?
- LOOPNZ LOOP1 ;;; (yes, continue spinning)
- MOV AL,DIS_KBD ;;; Get command to disable keyboard.
- OUT STATUS_PORT,AL ;;; Send it out.
- STI ;;; Reenable interrupts.
-
- NOP ; Window for interrupts.
-
- ; Wait for the keyboard to pick up
- ; the command:
- SUB CX,CX ; Clear counter for max cycles.
- CLI ;;; Disable interrupts.
- LOOP2: IN AL,STATUS_PORT ;;; Read the keyboard status port.
- TEST AL,INPT_BUF_FULL ;;; Is the command buffer still full?
- LOOPNZ LOOP2 ;;; (yes, continue spinning)
- STI ;;; Reenable interrupts.
-
- INT SCAN_INUM ; Read the scan code.
-
- JMP KB_INT_1A ; Go enter the mainline ROM code.
-
- KB_INT ENDP
-
- PAGE
- SUBTTL SCAN_INT -- Get a Keyboard Scan Code
-
- SCAN_INT PROC FAR ; Get a keyboard scan code.
- STI ; Enable interrupts.
-
- IN AL,KB_DATA ; Pick up the waiting scan code.
-
- PUSH AX ; Save the full scan.
- AND AL,NOT BREAK_BIT ; Eliminate the break bit.
- CMP AL,ESC_SCAN ; Is this an ESC?
- JE SAW_ESC ; (yes)
- CMP AL,TILDE_SCAN ; Is this a tilde?
- JE SAW_TILDE ; (yes)
-
- POP AX ; Restore the full code.
- IRET ; Return to caller.
-
-
- SAW_ESC:POP AX ; Restore the full scan code.
- AND AL,BREAK_BIT ; Retain the break bit.
- OR AL,TILDE_SCAN ; Remap into a tilde.
- IRET ; Return to the caller.
-
- SAW_TILDE:
- POP AX ; Restore the full scan code.
- AND AL,BREAK_BIT ; Retain the break bit.
- OR AL,ESC_SCAN ; Remap into an escape.
- IRET ; Return to the caller.
-
- SCAN_INT ENDP
-
-
- PAGE
- SUBTTL INIT -- Initialize and Exit-staying-resident
-
- INIT PROC NEAR ; Initialize and exit.
- ASSUME DS:CODESEG ; Entered with CS and DS pointing to
- ; the Program Segment Prefix, which
- ; the first 100H locations of CODESEG.
-
- ; Grab the keyboard hardware int.:
- MOV DX,OFFSET KB_INT ; Address of int. routine in DS:DX.
- MOV AL,KB_INUM ; Keyboard hardware interrupt.
- MOV AH,025H ; Set interrupt vector function.
- INT 21H ; Call DOS to take over the interrupt.
-
- ; Grab our special keyboard scan int.:
- MOV DX,OFFSET SCAN_INT ; Address of int. routine in DS:DX.
- MOV AL,SCAN_INUM ; Keyboard scan input request.
- MOV AH,025H ; Set interrupt vector function.
- INT 21H ; Call DOS to take over the interrupt.
-
- ; Return our environment block to
- ; free storage:
- MOV AX,ENV_SEG ; Get our environment block's segment.
- MOV ES,AX
- MOV AH,049H ; Free allocated memory.
- INT 21H ; Call DOS.
- ; Ignore possible error return.
-
- ; Terminate and stay resident. Start
- ; By calculating how much memory to
- ; leave allocated to this program:
- MOV DX,OFFSET INIT ; Don't need to retain init routine.
- ADD DX,0FH ; Round up to a paragraph.
- MOV CL,4
- SHR DX,CL
- MOV AL,0 ; Successful return.
- MOV AH,031H ; Terminate process & remain resident.
- INT 21H ; Call DOS.
-
- XOR AH,AH ; Emergency exit in case of DOS 1.
- INT 21H
-
- INIT ENDP
-
- CODESEG ENDS
-
- END BEGIN
-